home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / stk-3.002 / stk-3 / STk-3.1 / Src / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-21  |  5.6 KB  |  246 lines

  1. /*
  2.  * i o . c                    -- Low level I/O
  3.  * 
  4.  * Copyright ⌐ 1993-1996 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
  5.  * 
  6.  *
  7.  * Permission to use, copy, and/or distribute this software and its
  8.  * documentation for any purpose and without fee is hereby granted, provided
  9.  * that both the above copyright notice and this permission notice appear in
  10.  * all copies and derived works.  Fees for distribution or use of this
  11.  * software or derived works may only be charged with express written
  12.  * permission of the copyright holder.    
  13.  * This software is provided ``as is'' without express or implied warranty.
  14.  *
  15.  * This software is a derivative work of other copyrighted softwares; the
  16.  * copyright notices of these softwares are placed in the file COPYRIGHTS
  17.  *
  18.  *         Author: Erick Gallesio [eg@kaolin.unice.fr]
  19.  *    Creation date: ????
  20.  * Last file update: 14-Jul-1996 10:44
  21.  */
  22.  
  23. #ifdef WIN32
  24. #  include <windows.h>
  25. #  include <io.h>
  26. #  include <fcntl.h>
  27. #endif
  28.  
  29. #include "stk.h"
  30. #include "sport.h"
  31.  
  32. #define BUFFER_SIZE    512
  33. #define SYSTEM(instr)    { instr; }
  34. #define STRING_PORTP(f) (((struct str_iob *) f)->signature == SPORT_SIGNATURE)
  35.  
  36. #ifdef WIN32
  37.   FILE * STk_stdin, *STk_stdout, *STk_stderr;
  38. #endif
  39.  
  40. static char buffer[BUFFER_SIZE+1];
  41. static int  bufidx=0;
  42. static int  count=-1;
  43. static int  previous_char;
  44. static int  ungetted = 0;
  45. static int  filled=0;
  46.  
  47.  
  48. static void badport(int read)
  49. {
  50.   Err(read ? "String port is not open for reading"
  51.              : "String port is not open for writing",
  52.       NIL);
  53. }
  54.  
  55. #ifdef WIN32
  56. static DWORD Kbd_Thread(LPDWORD dumb)
  57. {
  58.   unsigned long size;
  59.  
  60.   for ( ; ; ) {
  61.     ReadFile(GetStdHandle(STD_INPUT_HANDLE), buffer, BUFFER_SIZE, &size, NULL);
  62.     buffer[size] = '\0';
  63.     count     = (int) size;
  64.     filled       = 1;
  65.   }
  66.   /* Never readched */
  67.   return 0;
  68. }
  69. #endif
  70.  
  71. void STk_StdinProc()
  72. {
  73.   for ( ; ; ) {
  74.     SYSTEM(count = read(fileno(STk_stdin), buffer, BUFFER_SIZE););
  75.     if (count != -1 || errno != EINTR) break;
  76.   }
  77.   filled = 1;
  78. }
  79.  
  80. int STk_getc(FILE *f)
  81. {
  82.   if (f == STk_stdin) {
  83.     if (ungetted) {
  84.       ungetted = 0;
  85.       return previous_char;
  86.     }
  87.     if (bufidx < count) return buffer[bufidx++];
  88.     else {
  89. #ifdef USE_TK
  90.       if (Tk_initialized) {
  91.     filled = 0;
  92.     while (!filled) {
  93.       Tcl_DoOneEvent(TK_DONT_WAIT);
  94.       if (Tk_GetNumMainWindows() <= 0) return EOF;
  95.     }
  96.       }
  97. #  ifndef WIN32
  98.       else
  99.     STk_StdinProc();
  100. #  endif
  101. #else 
  102.       /* This code is for snow only (Unix and Win32 flavours) */
  103.       STk_StdinProc();
  104. #endif
  105.       if (count <= 0) return EOF;
  106.       else {
  107.     bufidx = 1;
  108.     return *buffer;
  109.       }
  110.     }
  111.   }
  112.   else
  113.     if (STRING_PORTP(f)) {
  114.       register struct str_iob *g = (struct str_iob *)f;
  115.       if (!(g->flag & READING)) badport(TRUE);
  116.       return (--(g->cnt)>=0? ((int)*g->ptr++): EOF);
  117.     }
  118.     else {
  119.       int result;
  120.       SYSTEM(result=getc(f));
  121.       return result;
  122.     }
  123. }
  124.  
  125. int STk_ungetc(int c, FILE *f)
  126. {
  127.   if (f == STk_stdin) {
  128.     ungetted = 1;
  129.     previous_char = c;
  130.   }
  131.   else
  132.     if (STRING_PORTP(f)) {
  133.       register struct str_iob *g = (struct str_iob *)f;
  134.       if (g->ptr == g->base) Err("INTERNAL ERROR: cannont unget char", NIL);
  135.       if (!(g->flag & READING)) badport(TRUE);
  136.       g->ptr--;
  137.       g->cnt++;
  138.     }
  139.     else
  140.       SYSTEM(ungetc(c, f));
  141.   return c;
  142. }
  143.  
  144. int STk_putc(int c, FILE *f)
  145. {
  146.   if (STRING_PORTP(f)) {
  147.     register struct str_iob *g = (struct str_iob *)f;
  148.     register int tmp;
  149.     
  150.     if (!(g->flag & WRITING)) badport(FALSE);
  151.     if (++g->cnt == g->bufsiz) {
  152.       tmp     = g->bufsiz;
  153.       tmp    += tmp/2;
  154.       g->base     = must_realloc(g->base, tmp);
  155.       g->ptr     = g->base + g->bufsiz - 1; /* since base can have been moved */
  156.       g->bufsiz     = tmp;
  157.     }
  158.     *g->ptr++ = (char) c;
  159.   }
  160.   else {
  161.     SYSTEM(c=fputc(c, f));
  162.     /* Signal an error if write fails. We can't be very cute here */
  163.     if (c == EOF) Err("write-char: write error", NIL);
  164.   }
  165.   return c;
  166. }
  167.  
  168. int STk_puts(char *s, FILE *f)
  169. {
  170.   if (STRING_PORTP(f)) {
  171.     while (*s) STk_putc(*s++, f);
  172.     return 0;
  173.   }
  174.   else {
  175.     int result;
  176.     SYSTEM(result = fputs(s, f));
  177.     if (result == EOF) Err("write: write-error", NIL);
  178.     return result;
  179.   }
  180. }
  181.  
  182. int STk_eof(FILE *f)
  183. {
  184.   if (STRING_PORTP(f))
  185.     return (((struct str_iob *)f)->cnt <= 0);
  186.   else {
  187.     int result;
  188.     SYSTEM(result=feof(f));
  189.     return result;
  190.   }
  191. }
  192.  
  193.  
  194. char * STk_line_bufferize_io(FILE *f)
  195. {
  196.   char *buff;
  197.  
  198.   if ((buff=malloc(BUFFER_SIZE)) == NULL)
  199.     panic("Cannot allocate a line buffer for output file");
  200.   setvbuf(f, buff, _IOLBF, BUFFER_SIZE);
  201.   return buff;
  202. }
  203.  
  204.  
  205. #ifdef WIN32
  206.   /* 
  207.    * Windows apps don't have an associated console. The following code
  208.    * associate a console to the 3 standard files.  However, for some
  209.    * reason, even when closing stdin stdout and stderr, I was not able
  210.    * to remap console files on the first enties. Hence, the file name
  211.    * change from stdin to STk_stdin ...     
  212.    */
  213. #  include <windows.h>
  214. #  include <io.h>
  215. #  include <fcntl.h>
  216.  
  217.  
  218.   void STk_init_io(void)
  219.   {
  220.     HANDLE Fin, Fout, Ferr;
  221.     unsigned long dumb;
  222.     
  223.     if (AllocConsole()) {
  224.       Fin  = GetStdHandle(STD_INPUT_HANDLE);
  225.       Fout = GetStdHandle(STD_OUTPUT_HANDLE);
  226.       Ferr = GetStdHandle(STD_ERROR_HANDLE);
  227.       
  228.       fclose(stdin); fclose(stdout); fclose (stderr);
  229.       
  230.       STk_stdin     = fdopen(_open_osfhandle((long) Fin,  O_RDONLY), "r");
  231.       STk_stdout = fdopen(_open_osfhandle((long) Fout, O_APPEND), "w");
  232.       STk_stderr = fdopen(_open_osfhandle((long) Ferr, O_APPEND), "w");
  233.       
  234.       fflush(STk_stdout);
  235.       SetConsoleTitle("  *** STk console ***  ");
  236.       
  237.       /* Create a thread for reading keyboard */
  238. #ifdef USE_TK
  239.       CreateThread(NULL, 100, (LPTHREAD_START_ROUTINE) Kbd_Thread, NULL, 0, &dumb);
  240. #endif
  241.     }
  242.     else
  243.       STk_panic("Cannot create Win32 console");
  244.   }
  245. #endif
  246.